<template>
  <article class="page page-portscan-nodejs container">
    <h4 class="text-center">端口扫描器（NodeJS）</h4>
    <form role="form">
      <div class="form-group row">
        <label class="col-1 col-form-label">目 标</label>
        <div class="col-10">
          <input type="text" class="form-control" v-model.trim="target" placeholder="请输入目标IP">
        </div>
      </div>
      <div class="form-group row">
        <label class="col-1 col-form-label">端 口</label>
        <div class="col-10">
          <input type="text" class="form-control" v-model.trim="port" placeholder="请输入要扫描的端口">
        </div>
      </div>
      <div class="form-group row">
        <label class="col-1 col-form-label">方 式</label>
        <div class="col-5 check-wrapper">
          <label v-for="(v,i) in scanTypeList" :key="i">
            <input class="form-check-input" type="radio" :value="v.value" v-model="scanType">{{v.label}}
          </label>
        </div>
        <label class="col-1 col-form-label">DNS反向</label>
        <div class="col-4 check-wrapper">
          <label><input class="form-check-input" type="checkbox" v-model="reverse" />是</label>
        </div>
      </div>
      <div class="form-group row">
        <label class="col-1 col-form-label">延 迟</label>
        <div class="col-5">
          <input type="text" class="form-control" v-model.trim="timeout" placeholder="请输入延迟，单位ms">
        </div>
        <label class="col-1 col-form-label">套接max</label>
        <div class="col-4">
          <input type="text" class="form-control" v-model.trim="concurrency" placeholder="最大套接字数">
        </div>
      </div>
      <div class="form-group row">
        <label class="col-1 col-form-label"></label>
        <div class="col-10">
          <x-button type="primary" block :loading="loadingCount > 0" @click="scanPort">扫 描</x-button>
        </div>
      </div>
      <div class="form-group row">
        <label class="col-1 col-form-label">结 果</label>
        <div class="col-10">
          <textarea class="form-control" v-model.trim="result" rows="10" readonly></textarea>
        </div>
      </div>
    </form>
  </article>
</template>

<script>
let Evilscan = global.Evilscan || null

export default {
  name: 'portscan-nodejs',
  data () {
    return {
      target: '',
      port: '21,23,80,135,139,445,1433,3389,8080',
      timeout: 2000,
      concurrency: 500,
      scanType: 'tcpsyn',
      reverse: false,
      result: '',
      scanTypeList: [
        {label: 'SYN', value: 'tcpsyn'},
        {label: 'TCP', value: 'tcpconnect'},
        {label: 'UDP', value: 'udp'},
      ],
      loadingCount: 0
    }
  },
	mounted () {
		Evilscan = this.$sharedObject('Evilscan')
	},
  methods: {
    scanPort () {
      this.result = ''
      this.target = this.target || '127.0.0.1'
      this.loadingCount++
      new Evilscan({
        target: this.target,
        port: this.port,
        concurrency: this.concurrency,
        timeout: this.timeout,
        scan: this.scanType,
        status: 'TROU', // Timeout, Refused, Open, Unreachable
        banner: true,
        reverse: this.reverse,
      }, (err, scan) => {
        if (err) {
          console.log(err)
          return this.$toast('扫描错误:' + err)
        }
        scan.on('result', data => {
          console.log(data)
          this.result += `${data.ip}:${data.port} \t ${data.reverse || ''} \t ${data.status}\n`
        })
        scan.on('error', err => {
          console.log(err)
          this.$toast('扫描错误:' + err)
        })
        scan.on('done', () => {
          this.$toast('扫描完成')
          this.loadingCount--
        })
        scan.run()
      })
    }
  }
}
</script>

<style scoped lang="less">
@import "~@/assets/css/_mixins.less";
@import "~@/assets/css/_color.less";
textarea {
  resize: none;
}
.check-wrapper {
  label {
    margin-right: 1em;
    vertical-align: -webkit-baseline-middle;
  }
}
</style>
